package activitys;

import io.web.JSONConnector;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONObject;
import user.Base;
import misc.MyItemizedOverlay;
import nl.preflag.basewars.R;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.Spinner;
import android.widget.TextView;

/**
 * @author Patrick van Gils, 0787862, INF3M
 * BaseMap activity shows the mapview and it's options
 */

public class BaseMapActivity extends MapActivity implements LocationListener {
	
	ImageButton baseMapListButton, baseMapFriendButton;
	TextView creditsTextView, lastLoginTextView;
	Button createButton, baseMapSateliteButton, rankingButton, radiusButton;
	Spinner selectBaseSpinner;
	Drawable drawable;
	MyItemizedOverlay itemizedOverlay;
	String addressString, baseName, baseDesc;
	JSONConnector webby;
	JSONArray baseListJson, myInfoJson, allListJson, friendsListJson;
	JSONObject JSONResponse;
	HashMap<String, String> map, o;
	List<Overlay> mapOverlays;
	MapView mapView;
	List<HashMap<String, String>> fillMaps;
	MapController mc; // map controller
	Base otherBases[], myBases[]; // bases in spinner
	GeoPoint point, p; // own location and create base geo point
	double lat, lng; // Your own lat and lot (used by locationmanager)
    Boolean radius = false; // show radius around base
    int baseType = 1, baseHealth; // baseType: 1=me, 2=friend, 3=enemy
    String USER_ID;
    
    Double coordinates[] = {4.30802669, 51.83825099}; //lng, lat
    
	@Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.base_map);
        
        LocationManager lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
        lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000L, 500.0f, this);
        SharedPreferences pref = getSharedPreferences("programSettings", MODE_PRIVATE);
        USER_ID = pref.getString("userId", null);
        
        fillView();
        getMyInfo();
        fillOwnBases();
        fillBaseMap();

    }
	
	/**
	 * Fill the view
	 */
	private void fillView() {
		
		mapView = (MapView) findViewById(R.id.mapView);
		baseMapFriendButton = (ImageButton) findViewById(R.id.baseMapFriendButton);
		radiusButton = (Button) findViewById(R.id.baseMapRadiusButton);
		createButton = (Button) findViewById(R.id.baseMapCreateButton);
		baseMapSateliteButton = (Button) findViewById(R.id.baseMapSateliteButton);
		rankingButton = (Button) findViewById(R.id.baseMapHighScoresButton);
		selectBaseSpinner = (Spinner) findViewById(R.id.baseMapSelectBaseSpinner);
		creditsTextView = (TextView) findViewById(R.id.baseMapCreditsTextView);
		lastLoginTextView = (TextView) findViewById(R.id.baseMapLastLoginTextView);
		
		// add a click listener to the button
		baseMapFriendButton.setOnClickListener(new View.OnClickListener() {
	          public void onClick(View v) {
	        	  Intent connect = new Intent(BaseMapActivity.this, FriendListActivity.class);
	      		  startActivity(connect);
	          }
		});
		
		// add a click listener to the button
		createButton.setOnClickListener(new View.OnClickListener() {
	          public void onClick(View v) {
	        	  createBase();
	          }
		});
		
		// add a click listener to the button
		baseMapSateliteButton.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				changeMapView();
			}
		});
		
		// add a click listener to the button
		rankingButton.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				openRankings();
			}
		});
		
		// add a click listener to the button
		radiusButton.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				Intent mmIntent = new Intent(BaseMapActivity.this, BaseMapActivity.class);
				startActivityForResult(mmIntent, 0);
				finish();
			}
		});
	}
	
	/**
	 * Get player information (credits and latest login)
	 */
	private void getMyInfo() {
    	try 
    	{
    		webby = new JSONConnector();
    		myInfoJson = webby.connect("PlayerInformation/"+USER_ID+"", "result", true);
    		for(int i=0;i<myInfoJson.length();i++) 
    		{
    			JSONObject e = myInfoJson.getJSONObject(i);
    			creditsTextView.setText("Credits: " + e.getInt("credits"));
    			lastLoginTextView.setText("Last login: " + e.getString("latest_login"));
    		}    		
	   	} catch (Exception e) 
	   	{
	   		e.printStackTrace();
	   	}
	}
	
	/**
	 * Get own bases. Fill the spinner.
	 */
	private void fillOwnBases() {
		fillMaps = new ArrayList<HashMap<String, String>>();
    	try 
    	{
    		webby = new JSONConnector();
    		baseListJson = webby.connect("bases/user/"+USER_ID+"", "result", false);
    		myBases = new Base[baseListJson.length()];
    		for(int i=0;i<baseListJson.length();i++) 
    		{
    			map = new HashMap<String, String>();	
    			JSONObject e = baseListJson.getJSONObject(i);
    			if (e.getInt("health") != 0) {
    				myBases[i] = new Base(e.getInt("id"),e.getInt("player_id"),e.getDouble("loc_longitude"), e.getDouble("loc_latitude"), e.getInt("health"), e.getString("name"), e.getString("description"));
        			
        			map.put("id",  ""+e.getInt("id"));
        	    	map.put("player_id", ""+e.getInt("player_id"));
        	    	map.put("loc_longitude", ""+e.getDouble("loc_longitude"));
        	    	map.put("loc_latitude", ""+e.getDouble("loc_latitude"));
        	    	map.put("health", ""+e.getInt("health"));
        	    	map.put("name", ""+e.getString("name"));
        	    	map.put("description", ""+e.getString("description"));
        	    	fillMaps.add(map);	
    			} 
    		}
    		// Add my bases to the spinner
    		ArrayAdapter<Base> adapter = new ArrayAdapter<Base>( this, android.R.layout.simple_spinner_item, myBases );
    		adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    		selectBaseSpinner.setAdapter(adapter);
    		selectBaseSpinner.setOnItemSelectedListener(
                    new AdapterView.OnItemSelectedListener() {
                        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                            Base d = myBases[position];
                            point = new GeoPoint((int)(d.getLoc_latitude()*1E6),(int)(d.getLoc_longitude()*1E6));
                            mc = mapView.getController();
                            mc.animateTo(point);
                        }
                        public void onNothingSelected(AdapterView<?> parent) {
                        }
                    }
                );
    		
	   	} catch (Exception e) 
	   	{
	   		e.printStackTrace();
	   	}
	}
	
	/**
	 * Get all the bases from the database
	 */
	private void fillBaseMap() { 

		mapView.setBuiltInZoomControls(true);
		mapView.setSatellite(true);
		
		mapOverlays = mapView.getOverlays();
		fillMaps = new ArrayList<HashMap<String, String>>();
    	try 
    	{
    		webby = new JSONConnector();
    		allListJson = webby.connect("Base", "result", false);
    		otherBases = new Base[allListJson.length()];
    		for(int i=0;i<allListJson.length();i++) 
    		{
    			map = new HashMap<String, String>();	
    			JSONObject e = allListJson.getJSONObject(i);
    			
    			otherBases[i] = new Base(e.getInt("id"),e.getInt("player_id"),e.getDouble("loc_longitude"), e.getDouble("loc_latitude"), e.getInt("health"), e.getString("name"), e.getString("description"));
    			
    			map.put("id",  ""+e.getInt("id"));
    	    	map.put("player_id", ""+e.getInt("player_id"));
    	    	map.put("loc_longitude", ""+e.getDouble("loc_longitude"));
    	    	map.put("loc_latitude", ""+e.getDouble("loc_latitude"));
    	    	map.put("health", ""+e.getInt("health"));
    	    	map.put("name", ""+e.getString("name"));
    	    	map.put("description", ""+e.getString("description"));	
    	    			
    	    	if (e.getString("player_id").equalsIgnoreCase(USER_ID)) { 
    	    		// Don't show bases that area 'dead'
    	    		if (e.getInt("health") != 0) {
    	    			// Set baseType as 'me'
        	    		baseType = 1;
        	    		baseHealth = e.getInt("health");
        	    		
        	    		drawable = getResources().getDrawable(R.drawable.base);
        	    		point = new GeoPoint((int)(e.getDouble("loc_latitude")*1E6),(int)(e.getDouble("loc_longitude")*1E6));
        	    		
        	    		// itemizedOverlay (drawable, mapview, geopoint, radius boolean, player id, base id, base type (1=me, 2=friend, 3=enemy)
            	    	itemizedOverlay = new MyItemizedOverlay(drawable, mapView, point, radius, e.getInt("player_id"), e.getInt("id"), baseType, baseHealth);
            	    	
            	    	OverlayItem overlayItem = new OverlayItem(point, e.getString("name"), e.getString("description"));	
            	    	itemizedOverlay.addOverlay(overlayItem);
            	    	fillMaps.add(map);
            	        mapOverlays.add(itemizedOverlay);
    	    		}
    	    	} else if (e.getString("player_id").equalsIgnoreCase("14") || e.getString("player_id").equalsIgnoreCase("10") || e.getString("player_id").equalsIgnoreCase("13") || e.getString("player_id").equalsIgnoreCase("20")) {
    	    		if (e.getInt("health") != 0) {
    	    			// Set baseType as 'me'
        	    		baseType = 2;
        	    		baseHealth = e.getInt("health");
        	    		
        	    		drawable = getResources().getDrawable(R.drawable.base);
        	    		point = new GeoPoint((int)(e.getDouble("loc_latitude")*1E6),(int)(e.getDouble("loc_longitude")*1E6));
        	    		
        	    		// itemizedOverlay (drawable, mapview, geopoint, radius boolean, player id, base id, base type (1=me, 2=friend, 3=enemy)
            	    	itemizedOverlay = new MyItemizedOverlay(drawable, mapView, point, radius, e.getInt("player_id"), e.getInt("id"), baseType, baseHealth);
            	    	
            	    	OverlayItem overlayItem = new OverlayItem(point, e.getString("name"), e.getString("description"));	
            	    	itemizedOverlay.addOverlay(overlayItem);
            	    	fillMaps.add(map);
            	        mapOverlays.add(itemizedOverlay);
    	    		}
    	    	} else {
    	    		if (e.getInt("health") != 0) { 
        	    		// Set basteTyoe as 'enemy'
        	    		baseType = 3;
        	    		baseHealth = e.getInt("health");
        	    		
        	    		drawable = getResources().getDrawable(R.drawable.base);
        	    		point = new GeoPoint((int)(e.getDouble("loc_latitude")*1E6),(int)(e.getDouble("loc_longitude")*1E6));

        	    		// itemizedOverlay (drawable, mapview, geopoint, radius boolean, player id, base id, base type (1=me, 2=friend, 3=enemy)
            	    	itemizedOverlay = new MyItemizedOverlay(drawable, mapView, point, radius, e.getInt("player_id"), e.getInt("id"), baseType, baseHealth);
            	    	
        	    		OverlayItem overlayItem = new OverlayItem(point, e.getString("name"), e.getString("description"));	
        	    		itemizedOverlay.addOverlay(overlayItem);
            	    	fillMaps.add(map);
            	        mapOverlays.add(itemizedOverlay);
    	    		} 
    	    	}
    		}
    		mc = mapView.getController();
    		mc.animateTo(point);
    		mc.setZoom(16);
    		
	   	} catch (Exception e) 
	   	{
	   		e.printStackTrace();
	   	}
		
	}
	
	/**
	 * Toggle satelite mode
	 */
	private void changeMapView() {
		if (mapView.isSatellite() == true) {
			mapView.setSatellite(false);
			//baseMapSateliteButton.setText("Satelite on");
		} else {
			mapView.setSatellite(true);
			//baseMapSateliteButton.setText("Satelite off");
		}
	}
	
	/**
	 * Open rankings activity
	 */
	private void openRankings() {
		Intent mmIntent = new Intent(BaseMapActivity.this, RankListActivity.class);
		startActivityForResult(mmIntent, 0);
	}

	@Override
	protected boolean isRouteDisplayed() {
		return false;
	}
	
	/**
	 * Create base (Only called when GPS is turned on)
	 */
	private void createBase() {
		
		AlertDialog.Builder alert = new AlertDialog.Builder(this);
		final AlertDialog.Builder alert2 = new AlertDialog.Builder(this);

		alert.setTitle("Create base");
		alert.setMessage("Fill in a basename");
		final EditText input1 = new EditText(this);
		final EditText input2 = new EditText(this);
		alert.setView(input1);
		alert.setPositiveButton("Next", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int whichButton) {

					// Read the value from the input field
					baseName = input1.getText().toString();

					alert2.setTitle("Create base");
					alert2.setMessage("Fill in a base description");
					
					alert2.setView(input2);
					alert2.setPositiveButton("Create", new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog, int whichButton) {

								// Create base (location manager has set the long and the lat
								// Read the value from the input field
								baseDesc = input2.getText().toString();
								
								// Add value pair to send to webservice
								final List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(5);
				                nameValuePairs.add(new BasicNameValuePair("user_id", ""+USER_ID));
				                nameValuePairs.add(new BasicNameValuePair("lat", ""+lat));
				                nameValuePairs.add(new BasicNameValuePair("lon", ""+lng));
				                nameValuePairs.add(new BasicNameValuePair("basename", baseName));
				                nameValuePairs.add(new BasicNameValuePair("basedesc", baseDesc));
				                // Webservice	
				                try 
				                {
				                	webby = new JSONConnector();
				                	JSONResponse = webby.requestPostObject("/createbase", nameValuePairs);
				                	if (JSONResponse.getString("success").equals("false")) {
					               		 final AlertDialog ad = new AlertDialog.Builder(BaseMapActivity.this).create();
					            		 ad.setTitle("Error");
					            		 ad.setMessage(JSONResponse.getString("error"));
					            		 ad.setButton("OK", new DialogInterface.OnClickListener() {
					            			 public void onClick(DialogInterface dialog, int which) {
					            				 ad.dismiss();  
					            			 }
					            		 }); 
				            		 ad.show();
				                	} else {
				                		Intent mmIntent = new Intent(BaseMapActivity.this, BaseMapActivity.class);
						        		startActivity(mmIntent);
						        		finish();
				                	}
				                } catch (Exception e) {
				                	
				                }
						}	
					});
					alert2.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
						  public void onClick(DialogInterface dialog, int whichButton) {
							  // Canceled.
						  }
					});
					alert2.show();
			}
		});
		alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
			  public void onClick(DialogInterface dialog, int whichButton) {
				  // Canceled.
			  }
		});

		alert.show();
	}

	@Override
	public void onLocationChanged(Location location) {
		if (location != null) {
			lat = location.getLatitude();
			lng = location.getLongitude();
			p = new GeoPoint((int) (lat *1E6), (int) (lng *1E6));
			mc.animateTo(p); // TEST (bad gps makes it hard to test)
	    }
	}

	@Override
	public void onProviderDisabled(String provider) {
		createButton.setVisibility(View.GONE);
		//selectBaseSpinner.setVisibility(View.GONE);
		final AlertDialog ad = new AlertDialog.Builder(BaseMapActivity.this).create();
		 ad.setTitle("GPS off");
		 ad.setMessage("Certain options are not available when the GPS is turned off.");
		 ad.setButton("OK", new DialogInterface.OnClickListener() {
			 public void onClick(DialogInterface dialog, int which) {
				 ad.dismiss();  
			 }
		 }); 
		 ad.show();
	}

	@Override
	public void onProviderEnabled(String provider) {
		createButton.setVisibility(View.VISIBLE);
		selectBaseSpinner.setVisibility(View.VISIBLE);
	}

	@Override
	public void onStatusChanged(String provider, int status, Bundle extras) {
		// TODO Auto-generated method stub
		
	}
}
